﻿using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
#if WINDOWS_PHONE
using Microsoft.Xna.Framework.Input.Touch;
#endif
#if WINDOWS
using Microsoft.Xna.Framework.Storage;
#endif
using Microsoft.Xna.Framework.Media;
using Neat;
using Neat.MenuSystem;
using Neat.EasyMenus;
using Neat.GUI;
using Neat.Mathematics;
using Neat.Graphics;
using System.IO;
using Neat.Components;

#if KINECT
using Microsoft.Kinect;
using System.Diagnostics;
#endif

namespace RiverRaidX
{
    public partial class RiverRaidGame : Screen
    {
#if KINECT
        int lastSkelCount = 0;
        Vector2 lastRHand = Vector2.Zero;
        float lastHead = -1;
#endif
#if SPEECH
        float avgAudioLevel;
#if DEBUG
        int sp_c = 0;
#endif
#endif
        public override void HandleInput(GameTime gameTime)
        {
            if (!NoPlayer)
            {
                if (game.IsPressed(Keys.Space, Keys.LeftControl, Keys.RightControl) || game.IsPressed(Buttons.LeftStick) || game.IsPressed(Buttons.A)) Messages.Add(GameMessages.ShootRocket);
                if (game.IsPressed(Keys.Left) || game.IsPressed(Buttons.LeftThumbstickDown) || game.IsPressed(Buttons.DPadLeft)) Messages.Add(GameMessages.MoveLeft);
                if (game.IsPressed(Keys.Right) || game.IsPressed(Buttons.LeftThumbstickRight) || game.IsPressed(Buttons.DPadRight)) Messages.Add(GameMessages.MoveRight);
                if (game.IsPressed(Keys.Up) || game.IsPressed(Buttons.LeftThumbstickUp) || game.IsPressed(Buttons.DPadUp)) Messages.Add(GameMessages.SpeedUp);
                if (game.IsPressed(Keys.Down) || game.IsPressed(Buttons.LeftThumbstickDown) || game.IsPressed(Buttons.DPadDown)) Messages.Add(GameMessages.SlowDown);
                
#if SPEECH
                SpeechEngine sp = ((Game1)game).Speech;
                if (sp != null && sp.Recognizing)
                {
#if DEBUG
                    Debug.WriteLineIf((sp_c++ % 30) == 0, "Audio Level: " + sp.AudioLevel + "   Avg Level: " + avgAudioLevel, "Speech");
#endif
                    if (sp.AudioLevel > avgAudioLevel * 3.5f && sp.AudioLevel > 2)
                    {
                        Debug.WriteLine("Audio Level: " + sp.AudioLevel, "Speech");
                        Messages.Add(GameMessages.ShootRocket);
                    }
                    avgAudioLevel = MathHelper.Lerp(avgAudioLevel, sp.AudioLevel, 0.1f);
                }
#endif

#if KINECT
                KinectEngine k = ((Game1)game).Kinect;
                if (k != null)
                {
                    if (k.TrackedSkeletonsCount > 0 && lastSkelCount > 0)
                    {
                        var leftHip = k.ToVector2(JointType.HipLeft, new Vector2(300));
                        var rightHip = k.ToVector2(JointType.HipRight, new Vector2(300));
                        //var centerHip = k.ToVector2(Microsoft.Research.Kinect.Nui.JointID.HipCenter, new Vector2(300));
                        //var head = k.ToVector2(Microsoft.Research.Kinect.Nui.JointID.Head, new Vector2(300));
                        var rHand = k.ToVector2(JointType.WristRight, new Vector2(300));
                        var lHand = k.ToVector2(JointType.HandLeft, new Vector2(300));
                        var rElbow = k.ToVector2(JointType.ElbowRight, new Vector2(300));
                        var lElbow = k.ToVector2(JointType.ElbowLeft, new Vector2(300));
                        var cShoulder = k.ToVector2(JointType.ShoulderCenter, new Vector2(300));
                        var lShoulder = k.ToVector2(JointType.ShoulderLeft, new Vector2(300));
                        var rShoulder = k.ToVector2(JointType.ShoulderRight, new Vector2(300));
                        var head = k.ToVector3(JointType.Head, new Vector3(300));
                        var centerHip = k.ToVector3(JointType.HipCenter, new Vector3(300));
                        var kneeZ =
                            Math.Max(
                                k.ToVector3(JointType.KneeLeft, new Vector3(300)).Z,
                                k.ToVector3(JointType.KneeRight, new Vector3(300)).Z);

                        var threshold = Math.Abs(leftHip.X - centerHip.X) * 0.9f;

                        pxVelCoef = MathHelper.Lerp(pxVelCoef, (rHand.X - lastRHand.X) * 1.5f, 0.2f);

                        /*
                        if (head.X < leftHip.X - threshold) { Messages.Add(GameMessages.MoveLeft); }
                        else if (head.X > rightHip.X + threshold) { Messages.Add(GameMessages.MoveRight); }

                        if (head.X < leftHip.X) pxVelCoef = (head.X - leftHip.X) * 0.3f;
                        if (head.X > rightHip.X) pxVelCoef = (head.X - rightHip.X) * 0.3f; 
                        */

                        //if (rHand.X > rElbow.X + threshold) Messages.Add(GameMessages.MoveRight);
                        ////if (rHand.X < cShoulder.X) 
                        //if (rHand.X < rElbow.X - threshold)
                        //    Messages.Add(GameMessages.MoveLeft);

                        //if (rHand.Y > head.Y && rHand.Y < rightHip.Y && rHand.X > rightHip.X + threshold)
                        //    Messages.Add(GameMessages.MoveRight);
                        //if (lHand.Y > head.Y && lHand.Y < leftHip.Y && lHand.X < leftHip.X - threshold)
                        //    Messages.Add(GameMessages.MoveLeft);
                        if (head.X < leftHip.X - threshold * 0.6f) Messages.Add(GameMessages.MoveLeft);
                        if (head.X > rightHip.X + threshold * 0.6f) Messages.Add(GameMessages.MoveRight);

                        if (kneeZ < centerHip.Z - threshold * 0.5f && head.Z > centerHip.Z) Messages.Add(GameMessages.SlowDown);
                        else if (head.Z < centerHip.Z - threshold && head.Z < kneeZ) Messages.Add(GameMessages.SpeedUp);
                        
                        
                        //if (rHand.Y > centerHip.Y) Messages.Add(GameMessages.SlowDown);
                        //if (rHand.Y <= rShoulder.Y - threshold) Messages.Add(GameMessages.SpeedUp);
                        if (lHand.Y < lElbow.Y) Messages.Add(GameMessages.ShootRocket);

                        lastRHand = rHand;

                        if (state == GameStates.Game)
                        {
                            playerMesh.Offset(new Vector2(head.X - lastHead, 0) * 2.1f);
                        }
                        lastHead = head.X;
                    }
                    else
                    {
                        lastHead = playerMesh.GetPosition().X;
                    }
                    lastSkelCount = k.TrackedSkeletonsCount;
                }
#endif

                //if (game.IsTapped(Keys.R)) Reset();
                //if (game.IsTapped(Keys.D)) Die();

                if (game.IsReleased(Keys.Escape, Buttons.Back)) game.Console.Run("sh ingamemenu");
            }
            base.HandleInput(gameTime);
        }
    }
}